package com.zhuoyue.web.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.aliyuncs.utils.Base64Helper;
import com.zhuoyue.common.constant.AliOssResourceConstant;
import com.zhuoyue.common.constant.ResultCode;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@SuppressWarnings("AliDeprecation")
@RestController
@RequestMapping("/api/ali/oss")
/**
 * @ClassName: AppAliOssController
 * @Description: 阿里云图片内容上传
 * @author wjming
 * @Date 2021/2/14 19:24
 */
public class AppAliOssController {

    public static final String REGION = "cn-hangzhou";
    public static final String STS_API_VERSION = "2015-04-01";
    public static final Long TOKEN_EXPIRE_TIME = 3600L;
    public static final String ROLE_SESSION_NAME = "zyzn";

    @Value("${AliYun.Oss.keyId}")
    private String accessKeyId;
    @Value("${AliYun.Oss.KeySecret}")
    private String accessKeySecret;

    @SuppressWarnings("AliDeprecation")
    @GetMapping("/get_sign")
    public String getSign(HttpServletRequest request, HttpServletResponse response) {
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";
        String bucket = AliOssResourceConstant.OssResource.OSS_BUCKET_NAME;

        String uploadDir = request.getParameter("uploadDir");

        String host = "https://" + bucket + "." + endpoint;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST");
        response.addHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires,Content-Type, X-E4M-With");
        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            if (uploadDir == null) {
                uploadDir = "jizi";
            }
            String fileName = UUID.randomUUID().toString();
            String dir = "admin/" + uploadDir + "/" + (new SimpleDateFormat("yyyy/MM/dd/").format(new java.util.Date()));
            String callbackBody = "{\"callbackUrl\":\"http://oss.callback.logthin.com:23450\",\"callbackHost\":\"oss.callback.logthin.com\",\"callbackBody\":\"filename=" + fileName + "\",\"callbackBodyType\":\"application/x-www-form-urlencoded\"}";
            String base64CallbackBody = Base64Helper.encode(callbackBody, "utf-8");
            long expireTime = 600;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
            String postPolicy = client.generatePostPolicy(expiration, policyConds);
            String encodedPolicy = Base64Helper.encode(postPolicy, "utf-8");
            String postSignature = client.calculatePostSignature(postPolicy);
            Map<String, String> respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessKeyId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("filename", fileName);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            respMap.put("callback", base64CallbackBody);
            return JSON.toJSONString(respMap);
        } catch (Exception e) {
            return "";
        }
    }


    /**
     * 获取阿里云oss上传签名
     *
     * @return
     */

    @GetMapping("/oss_token")
    public String ossToken() {
        String bucketName = AliOssResourceConstant.OssResource.OSS_BUCKET_NAME;
        String roleArn = AliOssResourceConstant.OssResource.OSS_ROLE_ARN;
        // 此处必须为 HTTPS
        ProtocolType protocolType = ProtocolType.HTTPS;
        AssumeRoleResponse stsResponse = assumeRole(accessKeyId, accessKeySecret, roleArn, ROLE_SESSION_NAME, null, protocolType);
        if (stsResponse == null) {
            Map<String, String> respMap = new LinkedHashMap<>();
            respMap.put("result_code", ResultCode.SYS_ERROR);
            respMap.put("result_detail", "系统异常");
            return JSON.toJSONString(respMap);
        }
        Map<String, String> respMap = new LinkedHashMap<String, String>();
        respMap.put("AccessKeyId", stsResponse.getCredentials().getAccessKeyId());
        respMap.put("AccessKeySecret", stsResponse.getCredentials().getAccessKeySecret());
        respMap.put("SecurityToken", stsResponse.getCredentials().getSecurityToken());
        respMap.put("Expiration", stsResponse.getCredentials().getExpiration());
        respMap.put("bucketName", bucketName);
        return JSON.toJSONString(respMap);
    }

    private AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret, String roleArn, String roleSessionName, String policy, ProtocolType protocolType) {
        try {
            // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
            IClientProfile profile = DefaultProfile.getProfile(REGION, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            // 创建一个 AssumeRoleRequest 并设置请求参数
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setVersion(STS_API_VERSION);
            request.setMethod(MethodType.POST);
            request.setProtocol(protocolType);
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setDurationSeconds(TOKEN_EXPIRE_TIME);
            // 发起请求，并得到response
            AssumeRoleResponse response = client.getAcsResponse(request);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
